package com.huilan.config;

import com.alibaba.fastjson.JSONObject;
import com.huilan.model.User;
import com.huilan.util.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;

/**
 * 登录请求过滤器
 *
 * @author ghy
 */
@Slf4j
public class JwtLoginFilter extends UsernamePasswordAuthenticationFilter {

    private RedisUtil redisUtil;
    private AuthenticationManager authenticationManager;

    JwtLoginFilter(String url, AuthenticationManager authenticationManager) {
        this.authenticationManager = authenticationManager;
        super.setFilterProcessesUrl(url);
    }

    /**
     * 登录时需要验证时候调用
     */
    @Override
    public Authentication attemptAuthentication(HttpServletRequest req, HttpServletResponse res) {
        // 从输入流中获取到登录的信息
        try {
            User user = JSONObject.parseObject(req.getInputStream(), User.class);
            return authenticationManager.authenticate(
                    new UsernamePasswordAuthenticationToken(user.getUsername(), user.getPassword(), new ArrayList<>())
            );
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 验证成功后调用
     */
    @Override
    protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain, Authentication auth) throws IOException, ServletException {
        log.info("用户认证成功！");
        User user = ConstantUtil.LOGIN_USER;
        String username = auth.getName();
        //创建jwt
        String tokenStr = JwtUtil.createJWT(user);

        if(redisUtil==null){
            redisUtil = SpringUtil.getBean(RedisUtil.class);
        }

        JSONObject jsonObject = new JSONObject();
        jsonObject.put("token",tokenStr);
        jsonObject.put("username",username);

        //以用户名为key,token为value  并设置过期时间
        redisUtil.set(user.getUsername(), tokenStr, JwtUtil.EXPIRATION_TIME);
        response.setContentType("application/json");
        response.setCharacterEncoding("utf-8");
        response.getWriter().println(JSONObject.toJSON(ResponseResult.success(HttpStatus.OK.value(), "登陆成功！", jsonObject)));
    }

    /**
     * 验证失败后调用
     */
    @Override
    protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) throws IOException  {
        log.error("用户名或密码错误！");
        response.setContentType("application/json");
        response.setCharacterEncoding("UTF-8");
        response.getWriter().println(JSONObject.toJSON(ResponseResult.error(HttpStatus.UNAUTHORIZED.value(), "用户名或密码错误")));
    }
}
